#include "wsim_client.h"
#include <wsim/websocket_common.h>
#include <jsoncpp/json/json.h> /*jsoncpp -ljsoncpp*/

#include <iostream>
#include <map>
#include <QList>

#include "ui/mainform.h"
#include <QEvent>
#include <QCoreApplication>
#include <QDebug>
#include <QThread>
#include "./model/collectiongrabwindow.h"

#define MaxBufferSize 999999
mycfg* pConfig=NULL;

QEvent::Type WSIM_Event::m_WS_event = static_cast<QEvent::Type>(QEvent::registerEventType());
QEvent::Type WSIM_Event::m_WS_close = static_cast<QEvent::Type>(QEvent::registerEventType());
WSIM_Event::WSIM_Event(Type e):QEvent(e)
{}
WSIM_Event::WSIM_Event(Type e,int f):QEvent(e)
{
    fd=f;
}
WSIM_Event::WSIM_Event(Type e,int f,WebsocketData_Type t,char *p,unsigned int l):QEvent(e)
  {
    fd=f;
    datatype=t;
    if(l>0)
    {
        buf=(char*)calloc(l,sizeof(char));
        memcpy(buf,p,l);
    }
    bufLen=l;
}
WSIM_Event::~WSIM_Event()
{

}
static QObject *pObj=NULL;
/*******************************
 * 设置接收消息对象
 * *****************************/
void setObj(QObject *obj)
{
    pObj=obj;
}
/**********************************
 * 客户回调  向窗口发送消息
 * ***********************************/
int client_callBack(int fd,WebsocketData_Type datatype, char *buf, unsigned int bufLen)
{
    int ret=0;
    /*int (WSIM_client::*pcallBack)(int fd, WebsocketData_Type datatype, char *buf, unsigned int bufLen)=NULL;
    pcallBack=&WSIM_client::callBack;
    if(wsim!=NULL)
    {
        //qDebug()<<wsim;
        ret=(wsim->*pcallBack)(fd,datatype,buf,bufLen);
    }*/
    WSIM_Event e(WSIM_Event::m_WS_event,fd,datatype,buf,bufLen);
        QCoreApplication::sendEvent(pObj, &e);
    return ret;
}
int client_callCloseed(int fd){
    int ret=0;

    WSIM_Event e(WSIM_Event::m_WS_close,fd);
        QCoreApplication::sendEvent(pObj,&e);
    return ret;
}

int wsim_init(std::string ip,int prot)
{
    int fd=0;


    fd=client_init((char*)ip.c_str(),prot,"/null",(CallBackFun*)client_callBack,(CallCloseedFun*)client_callCloseed);
    if(fd<=0){

        return -1;
    }

    return fd;
}

int WSIM_client::wsfd=0;
int WSIM_client::m_pageSize=1024*16;



void WSIM_client::setfd(int fd)
{
    wsfd=fd;
}
void WSIM_client::closefd()
{
    if(wsfd>0){

        webSocket_send(wsfd,"quit",4,true,WDT_DISCONN);

    }
}

void WSIM_client::setPageSize(int size)
{
    m_pageSize=size;
}
int WSIM_client::getPageSize()
{
    return m_pageSize;
}

void WSIM_client::sendTEXT(std::string toname, std::string text)
{
    int ret;
    Json::Value sendRoot;
    sendRoot["stype"]="to";


                sendRoot["to"]=toname;
                sendRoot["message"]=text;
                std::string sendStr=sendRoot.toStyledString();
                //cout<<sendStr<<endl;
                if(wsfd>=0)
                {

                    ret=webSocket_send(wsfd,(char*)sendStr.c_str(),sendStr.size(),true,WDT_TXTDATA);

                }

}
void WSIM_client::sendTEXT_uuid(std::string uuid, std::string text)
{
    int ret;
    Json::Value sendRoot;
    sendRoot["stype"]="toUUID";


                sendRoot["toUUID"]=uuid;
                sendRoot["message"]=text;
                std::string sendStr=sendRoot.toStyledString();

                if(wsfd>=0){
                    qDebug()<<"发送文本:"<<QString::fromStdString(sendStr);

              ret=webSocket_send(wsfd,(char*)sendStr.c_str(),sendStr.size(),true,WDT_TXTDATA);

                }

}
void WSIM_client::sendTEXT_fd(int fd, std::string text)
{
    int ret;
    Json::Value sendRoot;
    sendRoot["stype"]="tofd";


                sendRoot["tofd"]=fd;
                sendRoot["message"]=text;
                std::string sendStr=sendRoot.toStyledString();

                if(wsfd>=0){
                    //qDebug()<<"发送文本开始";

                ret=webSocket_send(wsfd,(char*)sendStr.c_str(),sendStr.size(),true,WDT_TXTDATA);

                //qDebug()<<"发送"<<ret;
                }

}
/**
 * @brief WSIM_client::sendRequest 发送请求
 * @param tofd
 * @param magic
 * @param type
 * @param text
 */
void WSIM_client::sendRequest(int tofd,int magic,int type, std::string text)
{
    int ret;
    Json::Value sendRoot;
    sendRoot["stype"]="request";
                sendRoot["tofd"]=tofd;
                sendRoot["magic"]=magic;
                sendRoot["request"]=text;
                sendRoot["binType"]=type;
                int i=-1;
                i=WSIM_client::findLinkUp(tofd,0,magic);
                if(i>=0)
                {
                    sendRoot["label"]=m_linkList.at(i).label;
                    sendRoot["maxPageLen"]=m_linkList.at(i).maxPageLen;
                    sendRoot["maxPageNum"]=m_linkList.at(i).maxPageNum;
                }
                std::string sendStr=sendRoot.toStyledString();
                //cout<<sendStr<<endl;
                if(wsfd>=0)
                {

                    ret=webSocket_send(wsfd,(char*)sendStr.c_str(),sendStr.size(),true,WDT_TXTDATA);

                }
}
/**
 * @brief WSIM_client::sendTeamCommand 发送协助指令
 * @param tofd
 * @param magic
 * @param command
 */
void WSIM_client::sendTeamCommand(int tofd, int magic, std::__cxx11::string command)
{
    int ret;
    Json::Value sendRoot;
    sendRoot["stype"]="teamCommand";
                sendRoot["tofd"]=tofd;
                sendRoot["magic"]=magic;
                sendRoot["command"]=command;
                std::string sendStr=sendRoot.toStyledString();
                //cout<<sendStr<<endl;
                if(wsfd>=0)
                {

                    ret=webSocket_send(wsfd,(char*)sendStr.c_str(),sendStr.size(),true,WDT_TXTDATA);

                }
}

/**
 * @brief WSIM_client::sendResponse 应答
 * @param tofd
 * @param magic
 * @param response
 */
void WSIM_client::sendResponse(int tofd, int magic, std::string response)
{
    int ret;
    Json::Value sendRoot;
    sendRoot["stype"]="response";
                sendRoot["tofd"]=tofd;
                sendRoot["magic"]=magic;
                sendRoot["response"]=response;
                std::string sendStr=sendRoot.toStyledString();
                //cout<<sendStr<<endl;
                if(wsfd>=0)
                {

                    ret=webSocket_send(wsfd,(char*)sendStr.c_str(),sendStr.size(),true,WDT_TXTDATA);

                                }
}

/**
 * @brief WSIM_client::sendBYTE 发送二进制数据
 * @param head
 * @param buf
 */
int WSIM_client::sendBYTE(wsimBIN_head head, char *buf,unsigned int bufLen)
{
    int ret=0;
    if(wsfd>=0)
    {

            int hlen=sizeof(wsimBIN_head);
            int len=bufLen+hlen;
        char *dataBuf=(char*)calloc(len,sizeof(char));
        if(dataBuf!=NULL){
        memset(dataBuf, 0, len);
        head.dataLen=bufLen;
        memcpy(dataBuf,(char*)&head,hlen);
        if(bufLen>0){
            char *tmpchar=(dataBuf+hlen);
            memcpy(tmpchar,buf,bufLen);
        }

       //std:: cout<<"index:"<<head.index<<",bend:"<<head.bend<<std::endl;


            ret=webSocket_send(wsfd,dataBuf,len,true,WDT_BINDATA);


        if(dataBuf!=NULL)
            free(dataBuf);
        }

    }
    return ret;
}
/**
 * @brief WSIM_client::delayms 延时毫秒   重点在于处理接收和发送过程中产生的错误
 * @param ms
 */
void WSIM_client::delayms(int ms)
{
    //qDebug() << "当前线程: tid = " << QThread::currentThreadId();
    int ret;
    do{
        ret=webSocket_delayms(ms);
    }while(ret<0 && errno == EINTR);
}

void WSIM_client::hi()
{
    int ret;
    Json::Value sendRoot;
    sendRoot["stype"]="hi~";
    sendRoot["message"]="hi~,我来啦...";
    std::string sendStr=sendRoot.toStyledString();
    if(wsfd>=0)
    {

         //ret=push_socket_data(wsfd,(char*)sendStr.c_str(),sendStr.size(),WDT_TXTDATA);

       ret=webSocket_send(wsfd,(char*)sendStr.c_str(),sendStr.size(),true,WDT_TXTDATA);

    }
}



/**
 * @brief WSIM_client::addTeamView 添加一个远程协助任务
 * @param tfd
 * @param ffd
 * @param magic
 */
void WSIM_client::addTeamView(int tfd, int ffd, int magic,std::string filename)
{
    linkItem *item=new linkItem();
    item->ffd=ffd;//=0发送
    item->tfd=tfd;//=0接收
    item->magic=magic;
    item->binType=BINTYPE_TEAMVIEW;
    item->filename=filename;

    item->label="远程桌面";
    //std::cout<<item->label<<endl;
    item->pageIndex=0;
    QFile *m_localFile=new QFile(QString::fromStdString(filename));
        if(!m_localFile->open(QFile::ReadOnly)){
            qDebug()<<"打开传送文件出错，"<<QString::fromStdString(filename);
            return;
        }

    qint64 fileSize=m_localFile->size();
    item->maxPageLen=fileSize;
    item->maxPageNum=1;

    transferForm*f=&(MY_TRANSFER_FORM);
    if(f!=NULL)
    {
        f->addItem(tfd,ffd,magic,item->maxPageNum,"远程协助");
    }
    addLinkItem(*item);
}
/**
 * @brief WSIM_client::addLinkUp 沟通，提出问题，请求对方回答
 * @param tfd
 * @param filename
 */
void WSIM_client::addLinkUp(int tfd,int ffd,int magic, std::string filename)
{
    linkItem *item=new linkItem();    
    item->ffd=ffd;//=0发送
    item->tfd=tfd;//=0接收
    item->magic=magic;
    item->binType=BINTYPE_FILE;
    item->filename=filename;
    QString currentFileName=QString::fromStdString(filename);
    currentFileName=currentFileName.right(currentFileName.size()-currentFileName.lastIndexOf('/')-1);
    item->label=currentFileName.toStdString();
    //std::cout<<item->label<<endl;
    item->pageIndex=0;    
    QFile *m_localFile=new QFile(QString::fromStdString(filename));
        if(!m_localFile->open(QFile::ReadOnly)){
            qDebug()<<"打开传送文件出错，"<<QString::fromStdString(filename);
            return;
        }

    qint64 fileSize=m_localFile->size();
    item->maxPageLen=m_pageSize;
    int pagenum=fileSize/item->maxPageLen;
    int y=fileSize%(item->maxPageLen);
    if(y>0)
        pagenum+=1;
    item->maxPageNum=pagenum;

    transferForm*f=&(MY_TRANSFER_FORM);
    if(f!=NULL)
    {
        f->addItem(tfd,ffd,magic,pagenum,currentFileName);
    }
    addLinkItem(*item);


}
/**
 * @brief WSIM_client::addLinkItem 添加项
 * @param item
 */
void WSIM_client::addLinkItem(linkItem item)
{

    m_linkList.append(item);

}
void WSIM_client::delLinkUp(int tfd,int ffd, int magic)
{

    for(int i=0;i<m_linkList.size();i++) {

        if((m_linkList.at(i).tfd==tfd)&&(m_linkList.at(i).magic==magic)&&(m_linkList.at(i).ffd==ffd))
        {
           m_linkList.removeAt(i);
           break;
        }

    }
}
/**
 * @brief WSIM_client::findLinkUp 查找沟通
 * @param tfd
 * @param magic
 * @return 项的at
 */
int WSIM_client::findLinkUp(int tfd,int ffd, int magic)
{
    int index=-1;
    bool b=false;
    for( index=0;index<m_linkList.size();index++) {

        if((m_linkList.at(index).tfd==tfd)&&(m_linkList.at(index).magic==magic)&&(m_linkList.at(index).ffd==ffd))
        {
            b=true;
           break;
        }

    }
    if(!b)
       index=-1;
    return index;
}
linkItem WSIM_client::getLinkUp(int index)
{

            return m_linkList.at(index );

}

void WSIM_client::join(std::string nickname,std::string password)
{
    int ret;
    Json::Value sendRoot;
    sendRoot["stype"]="join";
    sendRoot["nickname"]=nickname;
    sendRoot["password"]=password;
    std::string sendStr=sendRoot.toStyledString();
    if(wsfd>=0){

        ret=webSocket_send(wsfd,(char*)sendStr.c_str(),sendStr.size(),true,WDT_TXTDATA);
        //ret=push_socket_data(wsfd,(char*)sendStr.c_str(),sendStr.size(),WDT_TXTDATA);

    }
}

void WSIM_client::reMood(std::string mood)
{
    int ret;
    Json::Value sendRoot;
    sendRoot["exec"]="reMood";
    sendRoot["param_1"]=mood;
    ret=execJson(sendRoot);
}
int WSIM_client::execJson(Json::Value sendRoot)
{
    int ret=0;
    sendRoot["stype"]="exec";
    std::string sendStr=sendRoot.toStyledString();

    if(wsfd>=0)
    {

        ret=webSocket_send(wsfd,(char*)sendStr.c_str(),sendStr.size(),true,WDT_TXTDATA);

          }
    return ret;
}

void WSIM_client::regUser(string nickname, string pwd)
{
    int ret;
    Json::Value sendRoot;
    sendRoot["exec"]="regUser";
    sendRoot["param_1"]=nickname;
    sendRoot["param_2"]=pwd;
    ret=execJson(sendRoot);
}
void WSIM_client::rePassword(string nickname, string oldpwd, string newpwd)
{
    int ret;
    Json::Value sendRoot;
    sendRoot["exec"]="rePassword";
    sendRoot["param_1"]=nickname;
    sendRoot["param_2"]=oldpwd;
    sendRoot["param_3"]=newpwd;
    ret=execJson(sendRoot);
}
void WSIM_client::reOrgan(string nickname, string organ)
{
    int ret;
    Json::Value sendRoot;
    sendRoot["exec"]="reOrgan";
    sendRoot["param_1"]=nickname;
    sendRoot["param_2"]=organ;
    ret=execJson(sendRoot);
}
void WSIM_client::reName(string nickname, string val)
{
    int ret;
    Json::Value sendRoot;
    sendRoot["exec"]="reName";
    sendRoot["param_1"]=nickname;
    sendRoot["param_2"]=val;
    ret=execJson(sendRoot);
}
void WSIM_client::reMobie(string nickname, string val)
{
    int ret;
    Json::Value sendRoot;
    sendRoot["exec"]="reMobileNumber";
    sendRoot["param_1"]=nickname;
    sendRoot["param_2"]=val;
    ret=execJson(sendRoot);
}
void WSIM_client::readUserInfo(string nickname)
{
    int ret;
    Json::Value sendRoot;
    sendRoot["exec"]="readUserInfo";
    sendRoot["param_1"]=nickname;
    ret=execJson(sendRoot);
}
void WSIM_client::readClients()
{
    int ret;
    Json::Value sendRoot;
    sendRoot["exec"]="readClients";
    //sendRoot["param_1"]=nickname;
    ret=execJson(sendRoot);
}
void WSIM_client::readRegClients()
{
    int ret;
    Json::Value sendRoot;
    sendRoot["exec"]="readRegClients";
    //sendRoot["param_1"]=nickname;
    ret=execJson(sendRoot);
}
void WSIM_client::readNoRegClients()
{
    int ret;
    Json::Value sendRoot;
    sendRoot["exec"]="readNoRegClients";
    //sendRoot["param_1"]=nickname;
    ret=execJson(sendRoot);
}
void WSIM_client::readOrganUser(string val)
{
    int ret;
    Json::Value sendRoot;
    sendRoot["exec"]="readOrganUser";
    sendRoot["param_1"]=val;
    ret=execJson(sendRoot);
}
void WSIM_client::readGroupUser(string val)
{
    int ret;
    Json::Value sendRoot;
    sendRoot["exec"]="readGroupUser";
    sendRoot["param_1"]=val;
    ret=execJson(sendRoot);
}
